home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / modelers / nff / filter.c next >
Internet Message Format  |  1992-12-02  |  6KB

  1. From pkh@vap.vi.ri.cmu.edu Tue Dec 13 21:30:04 1988
  2. Path: leah!itsgw!sun.soe.clarkson.edu!batcomputer!cornell!rochester!pt.cs.cmu.edu!vap.vi.ri.cmu.edu!pkh
  3. From: pkh@vap.vi.ri.cmu.edu (Ping Kang Hsiung)
  4. Newsgroups: comp.graphics
  5. Subject: nff filter for redundant polygon vertices
  6. Message-ID: <3865@pt.cs.cmu.edu>
  7. Date: 14 Dec 88 02:30:04 GMT
  8. Organization: Carnegie-Mellon University, CS/RI
  9. Lines: 244
  10.  
  11. I am posting the source code since among the people
  12. who requested for the source code, two of them are
  13. not reach-able from my system. Fortunately it's not a
  14. big program. Sorry for the inconvenience.
  15. ***
  16. /*
  17.  * program: nfff.c
  18.  *
  19.  *    a filter for NFF (Neutral File Format)
  20.  *    nfff [infile]
  21.  *    input: infile.nff or stdin
  22.  *    output: stdout
  23.  *
  24.  * input items other than polygons are copied to output directly.
  25.  * for polygons that have 2 or more identical vertices, the redundant
  26.  * vertices are filtered out and the "p <vert_count>" lines of
  27.  * the polygons are adjusted properly.
  28.  *
  29.  * the vertices degeneration cases occur in data produced by some
  30.  * automatic nff generation program when the resolution/prec. of
  31.  * generation exceeds that of the floating point format.
  32.  *
  33.  * definition of NFF: see nff.def
  34.  * bugs:
  35.  *    (1) handles polygons only. break if there are other obj. types
  36.  *    (2) MAX_VERT may cause trouble
  37.  *
  38.  * Fri Dec  2 16:41:27 EST 1988
  39.  * pkh@vap
  40.  *
  41.  * bugs fixed:
  42.  *
  43.  */
  44. #include    <stdio.h>
  45. #include    <math.h>
  46. /* #include    "/usr/pkh/include/all.h" */
  47. /* #include    "/usr/pkh/include/def3d.h" */
  48.  
  49. /* from "def3d.h" */
  50. typedef struct pt3d_struct {
  51.     float x, y, z;
  52. } pt3d, *pt3d_t;
  53. #define    FPRINT3d(fp, pt, newline) do { \
  54.     if (newline) \
  55.         fprintf(fp, "%g %g %g\n", pt.x, pt.y, pt.z); \
  56.     else \
  57.         fprintf(fp, "%g %g %g", pt.x, pt.y, pt.z); \
  58. } while (0)
  59. #define FSCAN3d(fp, pt) do { \
  60.     fscanf(fp,"%f %f %f", &(pt.x), &(pt.y), &(pt.z)); \
  61. } while(0)
  62. #define ASSIGN3d(p0, p1) do {p0.x=p1.x; p0.y=p1.y; p0.z=p1.z;} while(0)
  63. #define EQ3d(p0, p1) ((p0.x==p1.x)&&(p0.y==p1.y)&& (p0.z==p1.z))
  64.  
  65. /* from "all.h" */
  66. int    debug;
  67. #define POW2(y)        (1<<y)
  68. #define    ERROR_MSG_LENGTH    (200)
  69. #define DEBUG(arg) \
  70. do { \
  71.     char msg[ERROR_MSG_LENGTH]; \
  72.     if (debug) { \
  73.         sprintf arg; \
  74.          fprintf(stderr, "%s", msg); \
  75.     } \
  76. } while (0)
  77. #define ERROR(arg) \
  78. do { \
  79.     char msg[ERROR_MSG_LENGTH]; \
  80.         sprintf arg; \
  81.          fprintf(stderr, "%s", msg); \
  82.         exit(0); \
  83. } while (0)
  84.  
  85. #define        MAX_VERT    POW2(12)    /* 4k verts per poly */
  86. pt3d *v;    /* array of dim MAX_VERT */
  87.  
  88. FILE    *nfffile;
  89. char    infile[25];
  90.  
  91. /*
  92.  * for statistics
  93.  */
  94. int    total_byte;    /* total byte allocated */
  95. int    poly_id;
  96.  
  97. /*
  98.  * copy to end of line
  99.  */
  100. copy_line(ifp, ofp)
  101. FILE *ifp, *ofp;
  102. {
  103.     char c;
  104.     do {
  105.         putc((c=getc(ifp)), ofp);
  106.     } while (c!='\n');
  107. }
  108.  
  109. int read_poly(fp)
  110. FILE *fp;
  111. {
  112.     int             tv;
  113.     int             i;
  114.  
  115.     fscanf(fp, "%d", &tv);
  116.  
  117.     for (i = 0; i < tv; i++) {
  118.         FSCAN3d(fp,(v[i]));
  119.     }
  120.     return (tv);
  121. }
  122.  
  123. /*
  124.  * filter out degenerated (redundant) vertices
  125.  * and return the true vert count.
  126.  * complain when polygon has less than 3 vert
  127.  */
  128. int vert_filter(in_vert)
  129. int in_vert;
  130. {
  131.     int             head, tail;
  132.     int             tv, skip;
  133.  
  134.     /*
  135.      * filter out degenerated vertices. head points to the verified vert,
  136.      * tail scans down the vert list for new vert.
  137.      */
  138.     head = 0;        /* points to v[0] */
  139.     tail = head + 1;    /* points to v[1] */
  140.     tv = 1;            /* count one vert already (v[0]) */
  141.     skip = 0;        /* "skip occured" flag */
  142.     do {
  143.         while (EQ3d((v[head]), (v[tail]))) {
  144.             tail++;
  145.             if (tail == in_vert)
  146.                 goto last_vert;
  147.             skip = 1;
  148.         }
  149.         if (skip) {
  150.             ASSIGN3d((v[head + 1]), (v[tail]));
  151.         }
  152.         head++;
  153.         tail++;
  154.     } while (tail < in_vert);
  155.  
  156.     /* head now points to the last valid vert. compare last and first */
  157. last_vert:if (EQ3d((v[0]), v[head]))
  158.         tv = head;
  159.     else
  160.         tv = head + 1;
  161.     if (tv < 3) {
  162.         ERROR((msg, "poly %d has less than 3 vert\n", poly_id));
  163.         write_polygon(stderr, tv);    /* write vert */
  164.     }
  165.     if (debug) {
  166.         write_polygon(stderr, tv);    /* write vert */
  167.     }
  168.     return (tv);
  169. }
  170.  
  171. /*
  172.  * write out the cleaned-up polygons in nff format
  173.  * also print out the poly id
  174.  */
  175. write_polygon(fp, ply_vert)
  176. FILE *fp;
  177. int ply_vert;
  178. {
  179.     int             j;
  180.  
  181.     fprintf(fp, "# p%d\np %d\n", poly_id, ply_vert);
  182.     for (j = 0; j < ply_vert; j++) {
  183.         FPRINT3d(fp, (v[j]), 0);
  184.         fprintf(fp, "\n");
  185.     }
  186. }
  187.  
  188. /*
  189.  * for polygons: read-filter-write
  190.  * for the rest: read-write
  191.  */
  192. read_write(ifp, ofp)
  193. FILE *ifp, *ofp;
  194. {
  195.     char            key[20];
  196.     int             in_vert, out_vert;
  197.  
  198.     /* read "key" */
  199.     while (fscanf(ifp, "%s", key) != EOF) {
  200.  
  201.         DEBUG((msg, "get key %s\n", key));
  202.         if (strcmp(key, "p") == 0) {
  203.             in_vert = read_poly(ifp);
  204.             out_vert = vert_filter(in_vert);
  205.             write_polygon(ofp, out_vert);
  206.             poly_id++;
  207.         } else {
  208.             fprintf(ofp, "%s ", key);
  209.             copy_line(ifp, ofp);
  210.         }
  211.     };
  212. }
  213.  
  214. init()
  215. {
  216.     int             new_byte;
  217.  
  218.     new_byte = sizeof(pt3d) * MAX_VERT;
  219.     total_byte += new_byte;
  220.     v = (pt3d_t) malloc(new_byte);
  221.     DEBUG((msg, "v alloc %3dB; total %5dB\n", new_byte, total_byte));
  222.     if (v == NULL)
  223.         ERROR((msg, "v array alloc err\n"));
  224.  
  225.     poly_id = 0;
  226. }
  227.  
  228. main(argc, argv)
  229. int    argc;
  230. char    *argv[];
  231. {
  232.     if (argc == 1) {
  233.         nfffile= stdin;
  234.     }
  235.     else if (argc == 2) {
  236.         /* ap
  237. }pend .nff suffix */
  238.         sprintf(infile, "%s.nff", argv[1]);
  239.         if ((nfffile= fopen(infile, "r")) == NULL) {
  240.             ERROR((msg, "input file %s not found\n", infile));
  241.             exit(1);
  242.         }
  243.     } else {
  244.         ERROR((msg, "Usage: %s [file].nff\n", argv[0]));
  245.         exit(1);
  246.     }
  247.  
  248.     debug = 0;
  249.  
  250.     init();
  251.  
  252.     fprintf(stdout, "#\n# polygons filtered by nfffilter program\n");
  253.     fprintf(stdout, "# date:\n#\n");
  254.     read_write(nfffile, stdout);
  255. }
  256.